<?php
if(!defined('INSIDE')) {
	exit('Access Denied');
}

class tpl_loader{
	private $theme_name;
	private $tpldir;
	private $tplimgdir;
	private $outputdir;

	public function tpl_loader($theme_name = null){
		if(empty($theme_name)){
			global $_GVAR;
			$this->theme_name = $_GVAR['theme'];
		}
		else{
			$this->theme_name = $theme_name;
		}
		$this->tpldir = SITE_ROOT.'/template/'.$theme_name;
		$this->tplimgdir = SITE_ROOT.'/static/image/'.$theme_name;
		$gvar = site_core::GVAR();
		$this->outputdir =  SITE_ROOT.'/'.$gvar['dir']['cache']['tpl'];
	}
	
	public function load_tpl($tplfile, $force_refresh = false){
		$refresh = false;
		if($force_refresh === false){
			$gcfg = site_core::CFG();
			$refresh = $gcfg['testmode'];
		}
		return $this->parse_tpl($tplfile, $refresh);
	}
	
	private function parse_tpl($tplfile, $force_refresh = false){
		global $_GVAR;
		$tplfilename = util::file_abs('tpl', $this->theme_name.'/'.$tplfile);
		$outfilename = $this->outputdir.'/'.util::getcachetplfilename($this->theme_name, $_GVAR['language'], $tplfile);
		
		if(!$force_refresh){
			if(file_exists($outfilename) && filesize($outfilename) >= 0){
				if(filemtime($outfilename) > filemtime($tplfilename)){  //outfile is newer than tplfile
					return $outfilename;  // file_exists
				}
			}
		}
		
		$template = util::file_content($tplfilename);
		if($template === NULL) {
			exit('Missing File:'.$tplfile);
		}
		
		// (<!--){subtemplate (xxx)}(-->), include all subtemplates at the begginning
		$template = preg_replace("/[\n\r\t]*(\<\!\-\-)?\{subtemplate\s+([a-z0-9_:\/]+)\}(\-\-\>)?[\n\r\t]*/ies", "\$this->loadsubtemplate('\\2')", $template);
		
		$headeradd = <<<EOF
if(!defined('INSIDE')) exit('Access Denied');
header("Content-Type:text/html; charset=utf-8");
EOF;
		// header and sepecial header
		$template = "<?php\r\n{$headeradd}?>\r\n$template";
		
		// var: (${($xxx(->)xxx)([xxx])...})
		$var_regexp = "(\\\$\{(\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\-\>)?[a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*\})";
		// const: ${(xxx)}
		$const_regexp = "(\\\$\{[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\})";
		
		// filter \r \n
		$template = preg_replace("/([\n\r]+)\t+/s", "\\1", $template);
		// <!--{(xxx)}--> => {xxx}
		$template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);
		// {lang (xxx)} => yyy
		$template = preg_replace("/\{lang\s+(.+?)\}/ies", "\$this->languagevar('\\1')", $template);
		// {csstemplate (xxx)} => content of css template (convert var to the given value)
		$template = preg_replace("/[\n\r\t]*\{csstemplate\s+(.+?)\}[\n\r\t]*/ies", "\$this->loadcsstemplate('\\1')", $template);
		// {javascript (xxx)} => 
		$template = preg_replace("/[\n\r\t]*\{javascript\s+(.+?)\}[\n\r\t]*/ies", "\$this->loadjs('\\1')", $template);
		// {attachjs (xxx)} =>
		$template = preg_replace("/[\n\r\t]*\{attachjs\s+(.+?)\}[\n\r\t]*/ies", "\$this->attachjs('\\1')", $template);
		// {LF} => <?="\n"?->
		$template = str_replace("{LF}", "<?=\"\\n\"?>", $template);
		
		// {($xxx)} => <?=xxx?->
		
		// (($xxx(->)xxx)([xxx])...) => <?=$xxx(->)xxx[xxx]...)?->
		$template = preg_replace("/$var_regexp/es", "\$this->addquote('<?=\\1?>')", $template);
		// <?=<?=(($xxx(->)xxx)([xxx])...)?->?-> => <?=$xxx(->)xxx[xxx]...)?->
		$template = preg_replace("/\<\?\=\<\?\=$var_regexp\?\>\?\>/es", "\$this->addquote('<?=\\1?>')", $template);
		// ${(xxx)} => <?=${(xxx)})?->
		$template = preg_replace("/$const_regexp/es", "\$this->addquote('<?=\\1?>')", $template);
		// {echo (xxx)} => <? echo xxx; ?->
		$template = preg_replace("/[\n\r\t]*\{echo\s+(.+?)\}[\n\r\t]*/ies", "\$this->stripvtags('<? echo \\1; ?>')", $template);
		
		// {if (xxx)} => <? if(xxx) { ?->
		$template = preg_replace("/([\n\r\t]*)\{if\s+(.+?)\}([\n\r\t]*)/ies", "\$this->stripvtags('\\1<? if(\\2) { ?>\\3')", $template);
		// {elseif (xxx)} => <? } elseif(xxx) { ?->
		$template = preg_replace("/([\n\r\t]*)\{elseif\s+(.+?)\}([\n\r\t]*)/ies", "\$this->stripvtags('\\1<? } elseif(\\2) { ?>\\3')", $template);
		// {else (xxx)} => <? } else { ?->
		$template = preg_replace("/\{else\}/i", "<? } else { ?>", $template);
		// {/if (xxx)} => <? } ?->
		$template = preg_replace("/\{\/if\}/i", "<? } ?>", $template);
		// {loop (xxx) (yyy)} => if(is_array(xxx)) { foreach(xxx as yyy) { 
		$template = preg_replace("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\}[\n\r\t]*/ies", "\$this->looptags('\\1', '\\2')", $template);
		// {loop (xxx) (yyy) (zzz)} => if(is_array(xxx)) { foreach(xxx as yyy => zzz) {
		$template = preg_replace("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}[\n\r\t]*/ies", "\$this->looptags('\\1', '\\2', '\\3')", $template);
		// {/loop} => }
		$template = preg_replace("/\{\/loop\}/i", "<? }} ?>", $template);
		
		// {url (xxx)} => <? echo xxx; ?->
		$template = preg_replace("/[\n\r\t]*\{url\s+(.+?)\}[\n\r\t]*/ies", "\$this->genurl('\\1')", $template);
		
		
		// ?->\n...<? => " "
		$template = preg_replace("/\?\>[\n\r]*\<\?/s", " ", $template);
		// "(http)[:./x]?
		$template = preg_replace("/\"(http)?[\w\.\/:]+\?[^\"]+?&[^\"]+?\"/e", "\$this->transamp('\\0')", $template);
		$template = preg_replace("/\<\?(\s{1})/is", "<?php\\1", $template);
		$template = preg_replace("/\<\?\=(.+?)\?\>/is", "<?php echo \\1;?>", $template);
		
		if(!@$fp = fopen($outfilename, 'w')) {
			exit('Directory not found: '.dirname($outfilename));
		}
		flock($fp, 2);
		fwrite($fp, $template);
		fclose($fp);
		
		return $outfilename;
	}
	
	private function parse_sub_tpl($subtplfile){
		$subtplname = util::file_abs('tpl', $this->theme_name.'/'.$subtplfile);
		$outfilename = $this->outputdir.'/'.$this->theme_name.'_'.str_replace(array("/", "\\"), "_", $subtplfile).'.tpl.php';
		
		$content = util::file_content($subtplname);
		if($content === NULL){
			exit('Missing File:'.$subtplfile);
		}
		
		$content = preg_replace("/[\n\r\t]*(\<\!\-\-)?\{subtemplate\s+([a-z0-9_:\/]+)\}(\-\-\>)?[\n\r\t]*/ies", "\$this->loadsubtemplate('\\2')", $content);
		
		if(!@$fp = fopen($outfilename, 'w')) {
			exit('Directory not found: '.dirname($outfilename));
		}
		flock($fp, 2);
		fwrite($fp, $content);
		fclose($fp);
		
		return $outfilename;
	}
	
	private function loadsubtemplate($subtplfile) {
		$tplfile = $this->parse_sub_tpl($subtplfile);
		$content = util::file_content($tplfile);;
		if($content === NULL) {
			exit('Missing File:'.$subtplfile);
		} else {
			unlink($tplfile);
		}
		return $content;
	}
	
	private function languagevar($var) {
		return language::get_lang_var($var);
	}
	private function genurl($var) {
		$url = "/";
		if(!empty($var)) {
			$strs = explode('/', trim($var, "/ "));
			
			switch(count($strs)) {
				case 0:
					break;
				case 1:
					$url = $url.$strs[0].'.php';
					break;
				case 2:
					$url = $url.$strs[0].'.php?act='.$strs[1];
					break;
				default:
					$url = $url.$strs[0].'.php?act='.$strs[1].'&'.$strs[2];
					break;
			}
		}
		return $url;
	}
	
	function addquote($var) {
		$var = preg_replace("/\\\$\{(.+?)\}/s", "\\1", $var);
		return str_replace("\\\"", "\"", preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", "['\\1']", $var));
	}
	
	function looptags($var, $item_k, $item_v = null) {
		$expr = "<? if (is_array($var)) {";
		if(empty($item_v))
			$expr.="foreach($var as $item_k) {";
		else
			$expr.="foreach($var as $item_k => $item_v) {";
		$expr.="?>";
		return $expr;
	}
	
	function loadcsstemplate($css) {
		$cssfile = util::file_abs('tpl:css', $css, 'css');
		$cssfile_content = util::file_content($cssfile);
		if($cssfile_content === NULL){
			exit('Missging CSS File:'.$css);
		}
		$content = '<style>';
		$content.=$cssfile_content;
		// replace ${xxx} with string, such as: ${imgdir} = 'static/image/tplname'
		$content=preg_replace("/[\n\r\t]*\\\$\{(.+?)\}[\n\r\t]*/ies", "\$this->transcssvar('\\1')", $content);
		$content.='</style>';
		return util::compress_str($content);
	}
	
	function transcssvar($var){
		switch(strtolower(trim($var))){
			case "imgdir":
				return 'static/image/'.$this->theme_name;
			default:
				return '';
		}
	}
	
	function cssvtags($param, $content) {
		global $_G;
		$modules = explode(',', $param);
		foreach($modules as $module) {
			$module .= '::'; //fix notice
			list($b, $m) = explode('::', $module);
			if($b && $b == $_G['basescript'] && (!$m || $m == CURMODULE)) {
				$this->csscurmodules .= $content;
				return;
			}
		}
		return;
	}
	
	function stripvtags($expr, $statement = '') {
		$expr = str_replace("\\\"", "\"", preg_replace("/\<\?\=\\\$(.+?)\?\>/s", "\\1", $expr));
		$statement = str_replace("\\\"", "\"", $statement);
		return $expr.$statement;
	}
	
	function loadjs($js) {
		//$jspath = 'template/'.$this->theme_name.'/'.$js.'.js';
		//return "<script src=\"$jspath\" type=\"text/javascript\"></script>";
	  $jsfile = util::file_abs('tpl:js', $js, 'js');
	  $jsfile_content = util::file_content($jsfile);
	  if($jsfile_content === NULL){
	    exit('Missging JS File:'.$js);
	  }
	  $content = '<script type="text/javascript">';
	  $content.=$jsfile_content;
	  $content.='</script>';
	  return util::compress_str($content);
	}
	
	function attachjs($js) {
	  $jspath = util::file_abs('tpl:js', $js, 'js');
	  $ret = <<<JS_RET
  <script type="text/javascript">
  (function(d) {
    var tag=d.createElement("script");
    tag.type="text/javascript";
    tag.async=true;
    tag.src=d.location.protocol+"//"+d.location.hostname+(""==d.location.port?"":":"+d.location.port)+"/misc.php?mod=getjs&src=$js";
    d.getElementsByTagName("head")[0].appendChild(tag);
  }
  )(document);
  </script>
JS_RET;
	  return $ret;
	}
	
  function transamp($str) {
    //echo '<code>'.$str.'</code>';
    //$str = str_replace('&', '&amp;', $str);
    //$str = str_replace('&amp;amp;', '&amp;', $str);
    $str = str_replace('\"', '"', $str);
    return $str;
  }
}
?>